package com.demo.web3j.event;

import com.blockchain.scanning.chain.model.TransactionModel;
import com.blockchain.scanning.monitor.EthMonitorEvent;
import com.blockchain.scanning.monitor.filter.EthMonitorFilter;
import lombok.extern.slf4j.Slf4j;
import org.web3j.protocol.core.methods.response.EthBlock;

//监听区块链上的event
@Slf4j
public class EventDemo implements EthMonitorEvent  {


    /**
     * 筛选条件，如果遇到了符合条件的交易，会自动触发 call方法
     * 这些条件都是 并且的关系，必须要同时满足才行
     * 如果不想根据某个条件筛选，直接不给那个条件设置值就好了
     * 这个方法如果不实现，或者返回null， 那么就代表监听任意交易
     * 这里的逻辑其实就是 监听 to地址为 0x0B9b2f469232c761113a184B4148D2294C4C2DCf 的交易
     */
    @Override
    public EthMonitorFilter ethMonitorFilter() {
        return EthMonitorFilter.builder()
//                .setFromAddress("0x131231249813d334C58f2757037F68E2963C4crc") // 筛选 fromAddress 发送的交易
                .setToAddress("0x0B9b2f469232c761113a184B4148D2294C4C2DCf"); // 筛选 toAddress 或 合约地址 收到的交易
//                .setMinValue(BigInteger.valueOf(1)) // 筛选发送的主链币数量 >= minValue 的交易
//                .setMaxValue(BigInteger.valueOf(10)) // 筛选发送的主链币数量 <= maxValue 的交易
//                .setInputDataFilter( // 根据inputData筛选
//                        InputDataFilter.builder()
//                                .setFunctionCode(ERC20.TRANSFER.getFunctionCode()) // 函数签名（被调用的合约内的某方法）, 支持任意函数，这里的枚举只是一部分标准的合约函数
//                                .setTypeReferences( // 此方法的参数列表（仅类型）
//                                        new TypeReference<Address>(){},
//                                        new TypeReference<Uint256>(){}
//                                )
//                                .setValue("0x552115849813d334C58f2757037F68E2963C4c5e", null)// 筛选第几个参数 = 什么值

    }

    /**
     * 如果遇到了符合上面条件的交易，就会触发这个方法
     * transactionModel.getEthTransactionModel() 是一个交易对象，内部包含hash，value，from，to 等 所有的数据
     */
    @Override
    public void call(TransactionModel transactionModel) {
        System.out.println("----监听扫描处理数据开始---");
//        //节点
//        Web3j web3j = Web3jUtils.getWeb3j();
//        BigInteger blockNumber = transactionModel.getEthTransactionModel().getBlockNumber();
//        //通过区块号获取交易
//        Request<?, EthBlock> ethBlockRequest = web3j.ethGetBlockByNumber(DefaultBlockParameter.valueOf(blockNumber), true);
//        List<EthBlock.TransactionResult> transactions = ethBlockRequest.send().getBlock().getTransactions();
//        log.info("------------>transactions",transactions);
//        //----------------

        // 拿到符合监听条件的交易对象
        EthBlock.TransactionObject transactionObject = transactionModel.getEthTransactionModel().getTransactionObject();
        // 本条交易记录所在的块信息
        EthBlock ethBlock = transactionModel.getEthTransactionModel().getEthBlock();
        System.out.println("本条交易记录所在的块信息:----> " +ethBlock.getResult());
        System.out.println(transactionObject);

        // 该交易的hash
        // 0x8928bc5ca14548a4ffd25dd5a9973b680cbbf5850891f96ec5be744e18ed2256
        System.out.println(transactionObject.getHash());
        //通过交易hash就可以拿到交易详情对象跟交易的日志对象了
        // 交易所属块的哈希值
        // 0x01b363ca48badc5333824eab0a52fc1179a6acff2fcd01e8ea3a0c1f3d6476c3
        System.out.println(transactionObject.getBlockHash());
        // 交易发起人 0x71c77511401b1c7cb64c89823f54c5928c5a624a
        System.out.println(transactionObject.getFrom());
        // 交易接收人 0x0b9b2f469232c761113a184b4148d2294c4c2dcf
        System.out.println(transactionObject.getTo());
        // 交易的输入(方法签名+参数列表)
        // 前10个数是方法签名 methodId
        // 0xa9059cbb
        // 入参 1
        // 00000000000000000000000045998d65609965978f9da29a9b7db424ac45e682
        // 入参 2
        // 000000000000000000000000000000000000000000000000000000000000175e
        // 所以整个指就是这样的
        // 0xa9059cbb00000000000000000000000045998d65609965978f9da29a9b7db424ac45e682000000000000000000000000000000000000000000000000000000000000175e
        System.out.println(transactionObject.getInput());

        // 主币数量
        System.out.println(transactionObject.getValue());
        System.out.println(transactionObject.getValueRaw());

        // nonce
        System.out.println(transactionObject.getNonce());
        System.out.println(transactionObject.getNonceRaw());

        // 得到交易对象 这两个方法都是一样的返回地址而已
//        System.out.println(ethTransactionModel.get());
//        System.out.println(ethTransactionModel);

        //36010
        System.out.println(transactionObject.getGas());
        //10000000000
        System.out.println(transactionObject.getGasPrice());

        System.out.println("----监听扫描处理数据结束---");
    }
}
